package org.flashbrighton.as3bots.bots
{
	import org.flashbrighton.as3bots.bots.BaseBot;
	import org.flashbrighton.as3bots.components.ArmourComponent;
	import org.flashbrighton.as3bots.components.ChassisSize;
	import org.flashbrighton.as3bots.components.ComponentManager;
	import org.flashbrighton.as3bots.components.ExtraComponents;
	import org.flashbrighton.as3bots.events.*;
	import org.flashbrighton.as3bots.models.BotData;
	import org.flashbrighton.as3bots.utils.MathUtils;
	import org.flashbrighton.as3bots.views.ui.Message;
	
	public class Matt2Bot extends BaseBot
	{
		public function Matt2Bot()
		{
			super(ExtraComponents.ARMOUR, 0Xffce1e, ChassisSize.SMALL);
		}
		
		/** This method is called when your robot collides with another robot.
		 *
		 * @param event with information about the collision point
		 */
		override public function onHitBot(event:HitBotEvent):void
		{
			turnBy(event.collisionPoint/2);
		}

		/** This method is called when your robot collides with a wall.
		 *
		 * @param event with information about the collision point
		 */
		override public function onHitWall(event:HitWallEvent):void
		{
			writeMessage("Hit wall : " + event.collisionPoint);
			turnBy(MathUtils.sign(event.collisionPoint)*-0.5);
		}

		/** This method is called when your robot collides with a bomb.
		 *
		 * @param event with information about the collision point
		 */
		override public function onHitBomb(event:HitBombEvent):void
		{
		}

		/**
		 * This method is called when your robot sees another robot,
		 * i.e. when the robot's radar scan "hits" another robot.
		 *
		 * This method will only be called if the robot has the ExtraComponents.BOTSCANNER
		 *
		 * @param event containing the information about the nearest bot
		 */
		override public function onScanBot(event:ScanBotEvent):void
		{
			
		}

		/** This method is called when your robot receive data from its gem sensor.
		 *
		 *
		 * @param event containing the information about the nearest gem but also the list of all gems
		 */
		override public function onGemSensor(event:GemSensorEvent):void
		{
			writeMessage("gem Sensor: " + event.distance + " " + event.direction );
			if(Math.abs(event.direction)>0.2){
				turnBy(event.direction);
			}
		}

		/** This method is called when your robot receive data from its bomb sensor.
		 *
		 *
		 * @param event containing the information about the nearest bomb 
		 */
		override public function onBombSensor(event:BombSensorEvent):void
		{
			writeMessage("bomb Sensor: " + event.distance + " " + event.direction );
			if(event.distance < 4){
				if(Math.abs(event.direction)<0.4){
					turnBy(MathUtils.sign(event.direction)*-0.4);
				}
			}
		}

		/** This method is called when a gem is collected
		 *
		 * @param event containing the information about the collected gem
		 *
		 */
		override public function onCollectGem(event:CollectGemEvent):void
		{
			dropBomb();
		}

		/**
		 * The 'thinking' code for the bot.
		 * Code here is run every frame.
		 *
		 * @param data containing data about the current bot
		 */
		override public function update(data:BotData):void
		{
			//writeMessage("e/s: " + enginePower + "/" + steeringPower);
			currentAngle = data.angle + 1;
			if(turn){
				//writeMessage("-- until current"+(targetGreater?">":"<")+"target :" + currentAngle +  " ? "+ angleTarget);
				if((targetGreater && currentAngle > angleTarget)
					|| (!targetGreater && currentAngle < angleTarget)
					){
					// stop turning
					turn = false;
					steeringPower = 0;
					enginePower = 1;
				}
			}
		}
		
		private var currentAngle:Number = 0;
		private var angleTarget:Number = 0;
		private var targetGreater:Boolean;
		private var turn:Boolean = false;
		
		private function turnBy(angle:Number):void{
			if(turn) return;
			turn = true;
			writeMessage("Turn by " + angle + "with current " + currentAngle);
			angleTarget = currentAngle + angle;
			enginePower = 0;
			steeringPower = MathUtils.sign(angle);
			targetGreater = angle>0;
			if(angleTarget>=2 || angleTarget<0){
				angleTarget=(angleTarget+2)%2;
				targetGreater=!targetGreater;
			}
		}

	}
}